<template>
	<view v-if="visible" class="copper" @touchstart="touchStart" @touchmove.stop.prevent="touchMove" @touchend="touchEnd">
		<view class="tips">请确保移动或缩放后的图片不小于裁剪区域！</view>
		<view
			:id="id"
			:style="{
				width: `${image.width}px`,
				height: `${image.height}px`,
				transform: `translate(${-getImageX}px, ${-getImageY}px) translateZ(0) scale(${getImageScale})`
			}"
			:class="['copper-image', type]"
		>
			<img :src="src" />
		</view>
		<view class="copper-box" :style="{ top: box.top + 'px', left: box.left + 'px', width: box.width + 'px', height: box.height + 'px' }">
			<view class="h-line"></view>
			<view class="v-line"></view>
		</view>
		<view class="button">
			<button type="default" class="close" @click="close">取消</button>
			<button type="default" @click="confirm">裁剪</button>
		</view>
		<loading ref="loading"></loading>
		<!-- #ifdef H5 -->
		<view ref="canvasContainer"></view>
		<!-- #endif -->
		<!-- #ifdef MP-WEIXIN -->
		<canvas
			canvas-id="myCanvas"
			:style="{ width: box.width * pixelRatio + 'px', height: box.height * pixelRatio + 'px', position: 'absolute', top: -10 * box.height + 'px' }"
		></canvas>
		<!-- #endif -->
	</view>
</template>

<script>
import Loading from '../notice/loading.vue';
import h5 from './h5.js'
import mp from './mp.js'
export default {
	mixins: [
		// #ifdef MP-WEIXIN
		mp
		// #endif
		// #ifdef H5
		h5
		// #endif
	],
	props: {
		src: { type: String, default: '' },
		visible: { type: Boolean, default: false },
		isShare: { type: Boolean, default: false }
	},
	components: { Loading },
	data() {
		const info = uni.getSystemInfoSync();
		return {
			type: 'horizontal',
			id: 'image_' + this.getUUID(8),
			width: info.windowWidth,
			height: info.windowHeight,
			pixelRatio: 3,
			ratio: 750 / info.windowWidth,
			box: {
				width: 0,
				height: 0
			},
			image: {
				width: info.windowWidth,
				height: 0,
				top: 0,
				left: 0,
				scale: 1
			},
			moveX: 0,
			moveY: 0,
			scale: 0,
			symbol: Math.sqrt(Math.pow(info.windowWidth, 2) + Math.pow(info.windowHeight, 2)),
			path: '',
			canvas: undefined
		};
	},
	watch: {
		src: {
			handler(value) {
				if (value) {
					this.$nextTick(() => {
						this.calc(value);
					});
				}
			}
		},
	},
	computed: {
		getImageX() {
			return this.image.width / 2 - (this.image.left + this.moveX);
		},
		getImageY() {
			return this.image.height / 2 - (this.image.top + this.moveY);
		},
		getImageScale() {
			return this.image.scale + this.scale;
		}
	},
	methods: {
		reset() {
			const info = uni.getSystemInfoSync();
			this.startCropper = false;
			this.type = 'horizontal';
			this.width = info.windowWidth;
			this.height = info.windowHeight;
			this.pixelRatio = info.pixelRatio;
			this.ratio = 750 / info.windowWidth;
			this.box = {
				width: 0,
				height: 0
			};
			this.image = {
				width: info.windowWidth,
				height: 0,
				originWidth: 0,
				originHeight: 0,
				top: 0,
				left: 0,
				scale: 1
			};
			this.moveX = 0;
			this.moveY = 0;
			this.scale = 0;
			this.path = '';
			this.$emit('update:src', '');
		},
		getUUID(len, radix) {
			var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('');
			var uuid = [],
				i;
			radix = radix || chars.length;
			if (len) {
				for (i = 0; i < len; i++) uuid[i] = chars[0 | (Math.random() * radix)];
			} else {
				var r;
				uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-';
				uuid[14] = '4';
				for (i = 0; i < 36; i++) {
					if (!uuid[i]) {
						r = 0 | (Math.random() * 16);
						uuid[i] = chars[i == 19 ? (r & 0x3) | 0x8 : r];
					}
				}
			}
			return uuid.join('');
		},
		getImageInfo() {
			return new Promise(resolve => {
				const query = uni.createSelectorQuery().in(this);
				query
					.select('#' + this.id)
					.boundingClientRect(rect => {
						resolve(rect);
					})
					.exec();
			});
		},
		touchStart(e) {
			const touch0 = e.touches[0];
			const touch1 = e.touches[1];
			this.start = { touch0, touch1 };
			if (touch1) {
				this.opt = 'scale';
			} else {
				this.opt = 'move';
			}
		},
		touchMove(e) {
			const touch0 = e.touches[0];
			const touch1 = e.touches[1];
			this.move = { touch0, touch1 };
			if (this.opt === 'move') {
				this.moveX = touch0.pageX - this.start.touch0.pageX;
				this.moveY = touch0.pageY - this.start.touch0.pageY;
			} else {
				this.scale = this.getMoveLength(touch0, touch1);
			}
		},
		touchEnd(e) {
			this.image.top += this.moveY;
			this.moveY = 0;
			this.image.left += this.moveX;
			this.moveX = 0;
			this.image.scale += this.scale;
			this.scale = 0;
			this.startDistance = 0;
		},
		getMoveLength(touch0, touch1) {
			if (!touch0 || !touch1) {
				return 0;
			}
			if (!this.startDistance) {
				this.startDistance = Math.sqrt(Math.pow(touch0.pageX - touch1.pageX, 2) + Math.pow(touch0.pageY - touch1.pageY, 2));
			}
			const currentDistance = Math.sqrt(Math.pow(touch0.pageX - touch1.pageX, 2) + Math.pow(touch0.pageY - touch1.pageY, 2));
			return (currentDistance - (this.startDistance || 0)) / this.symbol;
		},
		close() {
			this.$refs.loading.hide();
			this.$emit('update:visible', false);
			this.reset();
		}
	}
};
</script>

<style lang="less" scoped>
.copper {
	position: fixed;
	top: 0;
	left: 0;
	right: 0;
	bottom: 0;
	z-index: 10;
	background-color: #000;
	// background-image: url('');
	.tips {
		position: fixed;
		top: 0;
		left: 0;
		right: 0;
		color: rgba(255, 255, 255, 0.8);
		line-height: 32rpx;
		font-size: 26rpx;
		padding: 24rpx;
		background-color: rgba(255, 255, 255, 0.2);
		z-index: 10;
		padding-left: 64rpx;
		&::before {
			content: '';
			position: absolute;
			left: 34rpx;
			top: 50%;
			transform: translateY(-50%);
			width: 18rpx;
			height: 18rpx;
			background-color: rgba(255, 255, 255, 0.8);
			border-radius: 50%;
		}
	}
	.copper-image {
		position: absolute;
		top: 50%;
		left: 50%;
		-webkit-backface-visibility: hidden;
		backface-visibility: hidden;
		-webkit-transform-style: preserve-3d;
		transform-style: preserve-3d;
		img {
			-webkit-touch-callout: none;
			-webkit-user-select: none;
			-moz-user-select: none;
			display: block;
			position: absolute;
			top: 0;
			left: 0;
			right: 0;
			bottom: 0;
			width: 100%;
			height: 100%;
		}
	}
	.copper-box {
		position: absolute;
		left: 0;
		border: solid 4rpx #fff;
		box-sizing: content-box;
		.h-line {
			position: absolute;
			top: 0;
			left: 0;
			right: 0;
			bottom: 0;
			&::before,
			&::after {
				content: '';
				position: absolute;
				top: 33.33%;
				height: 2rpx;
				left: 0;
				right: 0;
				background-color: #fff;
			}
			&::after {
				top: 66.66%;
			}
		}
		.v-line {
			position: absolute;
			top: 0;
			left: 0;
			right: 0;
			bottom: 0;
			&::before,
			&::after {
				content: '';
				position: absolute;
				left: 33.33%;
				width: 2rpx;
				top: 0;
				bottom: 0;
				background-color: #fff;
			}
			&::after {
				left: 66.66%;
			}
		}
	}
	.button {
		padding: 24rpx 40rpx;
		position: absolute;
		left: 0;
		right: 0;
		bottom: 0;
		z-index: 11;
		display: flex;
		padding-bottom: 32rpx;
		// padding-bottom: constant(safe-area-inset-bottom);
		// padding-bottom: env(safe-area-inset-bottom);

		button {
			flex-basis: 50%;
			padding: 15rpx 0;
			margin: 0;
			border-radius: 12rpx;
			font-size: 30rpx;
			font-weight: 400;
			color: #ffffff;
			line-height: 42rpx;
			background: #f39800;
			margin-right: 20rpx;
			&:last-child {
				margin-right: 0;
			}
			&.close {
				background-color: #999;
			}
		}
	}
}
</style>
